import 'dart:async';
import 'dart:convert';

import 'package:get/get.dart';

import '../ssh_service.dart';

class IpClusterCfgController extends GetxController {
  final ipCount = 0.obs;
  final clusterCount = 0.obs;
  late final StreamSubscription<SshCfgEvent> evt;

  @override
  void onInit() {
    super.onInit();
    SshService srv = Get.find();
    final updateIpList = (){
        final ipList = allIpListNotInCluster;
        ipCount.value = ipList.length;
        ipCount.refresh();
    };
    final updateClusterList = (){
        final clusterList = allClusterList;
        clusterCount.value = clusterList.fold(0, (previousValue, element) => previousValue+1);
        clusterCount.refresh();
    };
    updateClusterList();
    updateIpList();
    evt = srv.eventBus.on<SshCfgEvent>().listen((event) { 
      if (event.event == SshCfgEvent.eventIP) {
        updateIpList();
      } 
      else if (event.event == SshCfgEvent.eventCluster) {
        updateClusterList();
      }
    });
  }
  
  @override
  void onClose() {
    evt.cancel();
    super.onClose();
  }

  Iterable<String> get allIpListNotInCluster {
    return Get.find<SshService>().allIpListNotInCluster;
  }

  List<String>? getIpListByCluster(String cluster) {
    return Get.find<SshService>().clusters[cluster];
  }

  Iterable<String> get allClusterList {
    return Get.find<SshService>().allClusterList;
  }
  
  void updateSshCfg(String ip, String user, String pswd, int port) {
    SshService srv = Get.find();
    srv.updateSshCfg(ip, user, pswd, port);
  }

  void deleteIp(String ip) {
    Get.find<SshService>().deleteIp(ip);
  }

  void updateCluster(String cluster, List<String> ipList) {
    Get.find<SshService>().updateCluster(cluster, ipList);
  }

  void deleteCluster(String cluster) {
    Get.find<SshService>().deleteCluster(cluster);
  }

  Future<String> makeShell(String ip, int port, String cmd, String user, String pswd) async {
    SshService srv = Get.find();
    return await srv.makeShell(ip, port, cmd, user, pswd);
  }

  void addCluster(String cluster, String ip, String user, String pswd, int port) {
    final cmd = "etcdctl --cacert=/etc/rcos_global/tls_key/config_center/client/ca.pem "
                "--cert=/etc/rcos_global/tls_key/config_center/client/client.pem "
                "--key=/etc/rcos_global/tls_key/config_center/client/client-key.pem "
                "get --prefix /host/network_device | tail -n 1";
    makeShell(ip, port, cmd, user, pswd).then((value) {
      try {
        final ipList = <String>[];
        final res = jsonDecode(value) as List;
        res.forEach((node) { 
          final networkList = node["network_list"] as List;
          networkList.firstWhere((net) {
            if (net["device_name"] != "bond0")   return false;
            ipList.add(net["ipv4"]["ip_addr"]);
            return true;
          });
        });
        updateCluster(cluster, ipList);
        ipList.forEach((nodeip) {
          updateSshCfg(nodeip, user, pswd, port);
        });
      } catch(e) {
        final cmd2 = r"echo conf | nc 127.0.0.1 9639 | awk -F'[:=]' '/^server\./{print $2}'";
        makeShell(ip, port, cmd2, user, pswd).then((value) {
          try {
            final sipList = value.split('\n');
            final mipPart = ip.split(".");
            final ipList = <String>[];
            sipList.forEach((snodeip) {
              final sipPart = snodeip.split(".");
              if (sipPart.length!=4)  return;
              sipPart[0] = mipPart[0];
              sipPart[1] = mipPart[1];
              sipPart[2] = mipPart[2];
              final mip = sipPart.join(".");
              ipList.add(mip);
            });
            updateCluster(cluster, ipList);
            ipList.forEach((nodeip) {
              updateSshCfg(nodeip, user, pswd, port);
            });
          } catch (e) {
            Get.snackbar("error", "添加集群失败: $cluster");
          }
        });
      }
    });
  }
}